package com.hades.xq.miaoshao.service.impl;

import com.hades.xq.miaoshao.dao.ItemDOMapper;
import com.hades.xq.miaoshao.dao.ItemStockDOMapper;
import com.hades.xq.miaoshao.dataobject.ItemDO;
import com.hades.xq.miaoshao.dataobject.ItemStockDO;
import com.hades.xq.miaoshao.error.BusinessException;
import com.hades.xq.miaoshao.error.EmBusinessError;
import com.hades.xq.miaoshao.service.ItemService;
import com.hades.xq.miaoshao.service.PromoService;
import com.hades.xq.miaoshao.service.model.ItemModel;
import com.hades.xq.miaoshao.service.model.PromoModel;
import com.hades.xq.miaoshao.validator.ValidatorImpl;
import com.hades.xq.miaoshao.validator.ValidatorResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ValidatorImpl validator;

    @Autowired
    private ItemDOMapper itemDOMapper;

    @Autowired
    private ItemStockDOMapper itemStockDOMapper;

    @Autowired
    private PromoService promoService;

    @Override
    public boolean decreaseStock(Integer itemId, Integer amount) throws BusinessException {
        int affectedRow = itemStockDOMapper.descreaseStock(itemId, amount);
        //affectedRow > 0 is true 扣减成功，否则扣减失败
        return affectedRow > 0;
    }

    @Override
    @Transactional
    public ItemModel createItem(ItemModel itemModel) throws BusinessException {

        //校验入参
        ValidatorResult validatorResult = this.validator.validator(itemModel);
        if (validatorResult.isHasErrors()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, validatorResult.getErrMsg());
        }

        //转化itemmode->dataobject(itemDO)
        ItemDO itemDO = convertItemDoFromModel(itemModel);
        itemDOMapper.insertSelective(itemDO);
        itemModel.setId(itemDO.getId());

        ItemStockDO itemStockDO = this.convertItemStockDoFromModel(itemModel);
        //插入数据库
        itemStockDOMapper.insertSelective(itemStockDO);

        //返回创建完成的商品对象
        return this.getItemById(itemModel.getId());
    }

    @Override
    public List<ItemModel> listItem() {
        List<ItemDO> list = itemDOMapper.select();
        List<ItemModel> ItemModelList = list.stream().map(itemDO -> {
            ItemStockDO itemStockDO = itemStockDOMapper.selectByItemID(itemDO.getId());
            ItemModel itemModel = convertModelFromDataObject(itemDO, itemStockDO);
            return itemModel;
        }).collect(Collectors.toList());
        return ItemModelList;
    }

    @Override
    public ItemModel getItemById(Integer itemId) {
        ItemDO itemDO = itemDOMapper.selectByPrimaryKey(itemId);
        if (itemDO == null) {
            return null;
        }
        //获取库存数量
        ItemStockDO itemStockDO = itemStockDOMapper.selectByItemID(itemDO.getId());
        //将dataobject->model
        ItemModel itemModel = convertModelFromDataObject(itemDO, itemStockDO);

        //获取活动信息
        PromoModel promoModel = promoService.getPromoModelByItemId(itemModel.getId());
        //有秒杀活动并且还没有开始或者正在进行时
        if (promoModel != null && promoModel.getStatus() != 3) {
            itemModel.setPromoModel(promoModel);
        }
        return itemModel;
    }

    @Override
    @Transactional
    public void increaseSales(Integer itemId, Integer amount) throws BusinessException {
        itemDOMapper.increaseSale(itemId, amount);
    }

    private ItemModel convertModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(itemDO, itemModel);
        itemModel.setPrice(new BigDecimal(itemDO.getPrice()));
        if (itemStockDO != null) {
            itemModel.setStock(itemStockDO.getStock());
        }
        return itemModel;
    }

    private ItemDO convertItemDoFromModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemDO itemDO = new ItemDO();
        BeanUtils.copyProperties(itemModel, itemDO);
        itemDO.setPrice(itemModel.getPrice().doubleValue());
        return itemDO;
    }

    private ItemStockDO convertItemStockDoFromModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemStockDO itemStockDO = new ItemStockDO();
        itemStockDO.setItemId(itemModel.getId());
        itemStockDO.setStock(itemModel.getStock());
        return itemStockDO;
    }
}
